在開始操作前,我們需要先了解DOM是什麼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My title</title>
</head>
<body>
<h1>My header</h1>
<a href="">My link</a>
</body>
</html>
上述這段html程式碼,可以對照以下的圖片:
DOM=Document Object Model
文件中包含的元素,屬性,文字都被視為物件,所以是一個物件集合的文件檔案。
而構成文件的有:
如上述所說,我們知道了DOM裡面有節點,要操作前,我們必須先將元素節點取出,才可以操作。下面介紹幾種取得元素節點的方法,詳細請參照w3c裡面的解說及案例。
https://www.w3schools.com/js/js_htmldom_elements.asp
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My title</title>
</head>
<body>
<span id="result">Now:</span>
<!--得到 2020/9/9 下午5:01:07 -->
<script>
//建立時間日期
let current = new Date();
//取得具有該id的元素並回傳(d="result"),且賦值給變數result
let result = document.getElementById('result');
//將取的的元素用textContent插入上面宣告的變數current
result.textContent = current.toLocaleString();
</script>
</body>
</html>
這邊要注意的是如果id重複,getElementByID會回傳第一個符合的元素。
id="xxx"
下找出class="yyy"
的元素,就可以簡化成#xxx .yyy
。<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My title</title>
</head>
<body>
<ul id="list">
<li><a href="https://tw.yahoo.com/" class="ya">Yahoo</a></li>
<li><a href="https://www.google.com/?hl=zh_tw" class="gg">Google</a></li>
<li><a href="https://shopping.pchome.com.tw/" class="gg">PChome</a></li>
</ul>
<script>
//取出符合id="list" 且 class="gg"的全部元素節點,並用for 在console印出來
let list = document.querySelectorAll('#list .gg');
for (var i = 0, len = list.length; i < len; i++) {
console.log(list.item(i).href);
}
//結果:https://www.google.com/?hl=zh_tw
// https://shopping.pchome.com.tw/
</script>
</body>
</html>
上面介紹的getElementById、querySelectorAll在文件裡面還有getElementByXXX以及querySelector..等可以把元素取出來的方法;
對照起來是getElement/getElementByxxxx 對比 querySelector/querySelectorAll
兩種方法比較起來是getElementBy的方法速度較快,實作上面我自己是用querySelector比較多,寫起來比較直觀。
上述介紹的getElementById和querySelectorAll,這些方法都會以精確的定位取得元素,但效能不佳,原因是當這些方法在找元素的時候,會整個文件逐一搜尋。
因此DOM提供了另一種方法,以某個節點為出發點,透過位置的相對關係取得節點,這種方式與getxxxx/querySelector比較,程式碼會較為為冗長。
在實作上通常搭配使用,先用getxxxx/querySelector尋得特定元素後,再用節點尋訪的方式找到鄰近的節點。
節點與節點的關係大致上可以分層兩種,就是上述提到的父子、兄弟關係:
document
之外,每一個節點都會有個上層的節點,稱為父節點(Parent node),而父節點的下層,稱為子節點(Child node)。當我們了解了他們的關係後,接著我們透過程式碼來解釋:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form>
<label for="food">你最喜歡的食物</label>
<select id="food">
<option value="麥當勞">麥當勞</option>
<option value="肯德基">肯德基</option>
<option value="丹丹">丹丹</option>
</select>
</form>
<script>
//先取得id="food"的元素節點
let s =document.getElementById('food');
//用childNode去找id="food"節點下的子節點
let opts =s.childNodes;
//這邊我們得到 NodeList(7) [text, option, text, option, text, option, text],可以發現childNodes不只有本身的屬性會抓到外,也會抓到元素節點,以及字串節點。
console.log(opts);
//用for依序取得子節點,並在for裡面用nodeType判斷是否為元素,是的話才在console印出對應的值。
for (let i = 0,len=opts.length;i<len;i++){
let opt = opts.item(i);
if(opt.nodeType ===1){
console.log(opt.value);
}
}
//結果得到:
//麥當勞
//肯德基
//丹丹
</script>
</body>
</html>
透過上述例子我們可以發現,getElementById與childNode的搭配使用。
另外要特別補充的是nodeType,當我們要判斷節點類型時可以用nodeType判斷,下列網址有彙整nodeType屬性的回傳值:
(我們在上述的例子就是用回傳值1來判斷是否為元素節點。)
https://www.w3schools.com/jsref/prop_node_nodetype.asp
這邊用這兩個屬性來改寫一下上述的例子,使用這兩個屬性會直接抓到對應的元素,因此不用nodeType來判斷是否為元素,請看下列改寫的程式碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form>
<label for="food">你最喜歡的食物</label>
<select id="food">
<option value="麥當勞">麥當勞</option>
<option value="肯德基">肯德基</option>
<option value="丹丹">丹丹</option>
</select>
</form>
<script>
//先取得id="food"的元素節點
let s =document.getElementById('food');
//取得id="food"元素的第一個子元素
let child = s.firstElementChild;
//當子節點存在時以迴圈再console印出
while(child){
console.log(child.value);
child = child.nextElementSibling;
}
</script>
</body>
</html>
再上述程式碼中,結果與未改寫前相同,但我們省略nodeType去判斷是否為元素。
可以試看看,比較看看!
今天程式碼的篇幅有點長,但我覺得透過例子比較能理解今天的內容,
這邊在附上w3c中各種取得節點,尋訪節點的屬性及方法,以便參考裡面的例子,更加深元素節點的概念。(太多了,要一一介紹實在是講不完Q_Q)
https://www.w3schools.com/JSREF/dom_obj_all.asp
不得不說有w3c真的是太棒了!雖然是英文,但對比書本上的例子,再網站中的例子更為豐富以及實用!今天就沒有練習了,我自己是透過w3c中的練習來加強印象。
我們明天繼續!